package com.virtualperson.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.virtualperson.config.AliyunConfig;
import com.virtualperson.dto.StyleGenerationRequest;
import com.virtualperson.dto.StyleGenerationResponse;
import com.virtualperson.enums.StyleGenerationErrorCode;
import com.virtualperson.exception.ImageGenerationException;
import com.virtualperson.service.StyleGenerationService;
import com.virtualperson.util.ImageFileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class StyleGenerationServiceImpl implements StyleGenerationService {
    private static final String API_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image-generation/generation";
    private static final String TASK_API_URL = "https://dashscope.aliyuncs.com/api/v1/tasks";
    private static final int DEFAULT_MAX_ATTEMPTS = 120;
    private static final int DEFAULT_INTERVAL_SECONDS = 5;
    private static final String MODEL_NAME = "wanx-style-repaint-v1";

    private final RestTemplate restTemplate;
    private final AliyunConfig aliyunConfig;
    private final ImageFileUtil imageFileUtil;
    private final ObjectMapper objectMapper;

    public StyleGenerationServiceImpl(RestTemplate restTemplate, AliyunConfig aliyunConfig, ImageFileUtil imageFileUtil) {
        this.restTemplate = restTemplate;
        this.aliyunConfig = aliyunConfig;
        this.imageFileUtil = imageFileUtil;
        this.objectMapper = new ObjectMapper();
    }

    @Override
    public StyleGenerationResponse generateStyleImage(StyleGenerationRequest request) {
        try {
            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + aliyunConfig.getApiKey());
            headers.set("X-DashScope-Async", "enable"); // 启用异步调用

            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", MODEL_NAME);
            
            // 构建input对象
            Map<String, Object> inputMap = new HashMap<>();
            String imageUrl = request.getInput().getImageUrl();
            if (imageUrl == null || imageUrl.trim().isEmpty()) {
                throw new ImageGenerationException("image_url参数不能为空");
            }
            // 确保URL是完整的
            if (!imageUrl.startsWith("http://") && !imageUrl.startsWith("https://")) {
                imageUrl = "https://" + imageUrl;
            }
            inputMap.put("image_url", imageUrl.trim());
            inputMap.put("style_index", request.getInput().getStyleIndex());
            if (request.getInput().getStyleRefUrl() != null) {
                String styleRefUrl = request.getInput().getStyleRefUrl();
                if (!styleRefUrl.startsWith("http://") && !styleRefUrl.startsWith("https://")) {
                    styleRefUrl = "https://" + styleRefUrl;
                }
                inputMap.put("style_ref_url", styleRefUrl.trim());
            }
            requestBody.put("input", inputMap);

            // 记录完整的请求信息
            String requestJson = objectMapper.writeValueAsString(requestBody);
            log.info("=== 风格生成请求详情 ===");
            log.info("请求URL: {}", API_URL);
            log.info("请求头: Authorization=Bearer {}, X-DashScope-Async={}", 
                    aliyunConfig.getApiKey().substring(0, 8) + "***", 
                    headers.getFirst("X-DashScope-Async"));
            log.info("请求体: {}", requestJson);
            log.info("图片URL: {}", imageUrl);
            log.info("风格索引: {}", request.getInput().getStyleIndex());
            if (request.getInput().getStyleRefUrl() != null) {
                log.info("风格参考URL: {}", request.getInput().getStyleRefUrl());
            }
            log.info("=====================");

            // 发送请求
            HttpEntity<String> httpEntity = new HttpEntity<>(requestJson, headers);
            ResponseEntity<String> responseEntity = restTemplate.exchange(
                API_URL,
                HttpMethod.POST,
                httpEntity,
                String.class
            );

            // 记录响应信息
            log.info("=== 风格生成响应详情 ===");
            log.info("响应状态码: {}", responseEntity.getStatusCode());
            log.info("响应头: {}", responseEntity.getHeaders());
            log.info("响应体: {}", responseEntity.getBody());
            log.info("=====================");

            if (responseEntity.getStatusCode() != HttpStatus.OK) {
                String errorMessage = String.format("API调用失败: HTTP状态码=%d, 响应=%s", 
                    responseEntity.getStatusCodeValue(), responseEntity.getBody());
                log.error(errorMessage);
                throw new ImageGenerationException(errorMessage);
            }

            // 解析响应
            StyleGenerationResponse response = objectMapper.readValue(
                responseEntity.getBody(), 
                StyleGenerationResponse.class
            );

            if (response == null) {
                String errorMessage = "API返回响应为空";
                log.error(errorMessage);
                throw new ImageGenerationException(errorMessage);
            }

            // 检查响应是否包含必要的字段
            if (response.getOutput() == null || response.getOutput().getTaskId() == null) {
                String errorMessage = "API响应缺少必要字段";
                log.error("API响应缺少必要字段: {}", responseEntity.getBody());
                throw new ImageGenerationException(errorMessage);
            }

            log.info("风格生成任务已创建: taskId={}, requestId={}", 
                    response.getOutput().getTaskId(), 
                    response.getRequestId());

            return response;
        } catch (HttpClientErrorException e) {
            String errorMessage = String.format("API调用失败(客户端错误): HTTP状态码=%d, 响应=%s", 
                e.getRawStatusCode(), e.getResponseBodyAsString());
            log.error(errorMessage, e);
            throw new ImageGenerationException(errorMessage, e);
        } catch (HttpServerErrorException e) {
            String errorMessage = String.format("API调用失败(服务器错误): HTTP状态码=%d, 响应=%s", 
                e.getRawStatusCode(), e.getResponseBodyAsString());
            log.error(errorMessage, e);
            throw new ImageGenerationException(errorMessage, e);
        } catch (RestClientException e) {
            String errorMessage = "API调用失败: " + e.getMessage();
            log.error(errorMessage, e);
            throw new ImageGenerationException(errorMessage, e);
        } catch (Exception e) {
            String errorMessage = "调用风格生成API失败: " + e.getMessage();
            log.error(errorMessage, e);
            throw new ImageGenerationException(errorMessage, e);
        }
    }

    @Override
    public StyleGenerationResponse getTaskStatus(String taskId) {
        try {
            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + aliyunConfig.getApiKey());

            // 构建请求URL，将taskId作为路径参数
            String taskUrl = TASK_API_URL + "/" + taskId;
            log.info("查询任务状态: taskId={}, URL={}", taskId, taskUrl);
            log.debug("请求头: {}", headers);

            // 发送GET请求
            HttpEntity<String> httpEntity = new HttpEntity<>(headers);
            ResponseEntity<String> responseEntity = restTemplate.exchange(
                taskUrl,
                HttpMethod.GET,
                httpEntity,
                String.class
            );

            log.info("收到响应: status={}, body={}", responseEntity.getStatusCode(), responseEntity.getBody());

            if (responseEntity.getStatusCode() != HttpStatus.OK) {
                String errorMessage = String.format("查询任务状态失败: HTTP状态码=%d, 响应=%s", 
                    responseEntity.getStatusCodeValue(), responseEntity.getBody());
                log.error(errorMessage);
                throw new ImageGenerationException(errorMessage);
            }

            // 解析响应
            StyleGenerationResponse response = objectMapper.readValue(
                responseEntity.getBody(), 
                StyleGenerationResponse.class
            );

            if (response == null) {
                String errorMessage = "API返回响应为空";
                log.error(errorMessage);
                throw new ImageGenerationException(errorMessage);
            }

            // 检查响应状态
            if (response.getOutput() != null && response.getOutput().getStatus() != null) {
                log.info("任务状态: {}", response.getOutput().getStatus());
            } else {
                log.warn("响应中缺少状态信息: {}", responseEntity.getBody());
            }

            return response;
        } catch (HttpClientErrorException e) {
            String errorMessage = String.format("查询任务状态失败(客户端错误): HTTP状态码=%d, 响应=%s", 
                e.getRawStatusCode(), e.getResponseBodyAsString());
            log.error(errorMessage, e);
            throw new ImageGenerationException(errorMessage, e);
        } catch (HttpServerErrorException e) {
            String errorMessage = String.format("查询任务状态失败(服务器错误): HTTP状态码=%d, 响应=%s", 
                e.getRawStatusCode(), e.getResponseBodyAsString());
            log.error(errorMessage, e);
            throw new ImageGenerationException(errorMessage, e);
        } catch (RestClientException e) {
            String errorMessage = "查询任务状态失败: " + e.getMessage();
            log.error(errorMessage, e);
            throw new ImageGenerationException(errorMessage, e);
        } catch (Exception e) {
            String errorMessage = "查询任务状态时发生未知错误: " + e.getMessage();
            log.error(errorMessage, e);
            throw new ImageGenerationException(errorMessage, e);
        }
    }

    @Override
    public StyleGenerationResponse waitForTaskCompletion(String taskId, int maxAttempts, int intervalSeconds) {
        log.info("等待任务完成: taskId={}, maxAttempts={}, intervalSeconds={}", 
                taskId, maxAttempts, intervalSeconds);

        for (int attempt = 1; attempt <= maxAttempts; attempt++) {
            StyleGenerationResponse response = getTaskStatus(taskId);
            
            if (response.isCompleted()) {
                if (response.isSuccessful()) {
                    log.info("任务成功完成: taskId={}", taskId);
                    return response;
                } else {
                    String errorMessage = String.format("任务执行失败: %s", 
                            response.getOutput().getMessage() != null ? 
                            response.getOutput().getMessage() : "未知错误");
                    log.error(errorMessage);
                    throw new ImageGenerationException(errorMessage);
                }
            }

            if (attempt < maxAttempts) {
                log.info("任务仍在进行中，等待{}秒后重试: taskId={}, attempt={}/{}", 
                        intervalSeconds, taskId, attempt, maxAttempts);
                try {
                    TimeUnit.SECONDS.sleep(intervalSeconds);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new ImageGenerationException("等待任务完成被中断", e);
                }
            }
        }

        throw new ImageGenerationException(String.format("等待任务完成超时: taskId=%s, maxAttempts=%d", 
                taskId, maxAttempts));
    }

    @Override
    public StyleGenerationResponse waitForTaskCompletion(String taskId) {
        return waitForTaskCompletion(taskId, DEFAULT_MAX_ATTEMPTS, DEFAULT_INTERVAL_SECONDS);
    }
} 